package org.anddev.andengine.extension.svg.node;
/**
 * @author Eric Depta
 * @since 01:14:00 - 28.02.2011
 */
import java.util.List;

import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.extension.svg.SVGDoc;
import org.anddev.andengine.extension.svg.SVGPath;
import org.anddev.andengine.extension.svg.SVGStyle;
import org.anddev.andengine.extension.svg.util.parser.ParserUtil;
import org.anddev.andengine.extension.svg.util.physic.ExtendedPhysicsFactory;
import org.anddev.andengine.extension.svg.util.render.Render;
import org.anddev.andengine.extension.svg.util.render.TriangleShape;
import org.anddev.andengine.extension.svg.util.transform.TransformDoc;
import org.anddev.andengine.util.MathUtils;
import org.anddev.andengine.util.SAXUtils;
import org.xml.sax.Attributes;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class PathNode extends DrawablePhysicNode {
	protected SVGPath svgPath = null;
	
	public PathNode(final SVGDoc pSVGDoc){
		super(pSVGDoc);
	}
	
	public void create(final Attributes pAttributes, final TransformDoc pTransform){
		super.create(pAttributes, pTransform);
	}
	
	@Override
	protected void createPhysics(Shape pShape, String pName, Attributes pAttributes) {
		if(this.svgPath.isValid()){
			if(super.isHasPhysic()){
				Body body = null;
				if(this.svgPath.isClosed()){
					body = ExtendedPhysicsFactory.createTrianglulatedBody(
						super.mSVGDoc.mPhysicsWorld, 
						pShape,
						this.svgPath.getPhysicVerticesTriangleList(super.mTransformation),
						BodyType.values()[SAXUtils.getIntAttribute(pAttributes, TAG_ATTRIBUTE_BODYTYPE, 0)], 
						super.createFixtureDef(pAttributes)
					);
				}else{
					body = ExtendedPhysicsFactory.createLinesBody(
						super.mSVGDoc.mPhysicsWorld, 
						pShape,
						this.svgPath.getPhysicVertices(super.mTransformation), 
						BodyType.values()[SAXUtils.getIntAttribute(pAttributes, TAG_ATTRIBUTE_BODYTYPE, 0)], 
						super.createFixtureDef(pAttributes)
					);
				}
				super.setBodyOptions(pAttributes, body);
				
				//-- Init Rotation  
				body.setTransform(
					body.getWorldCenter(),
					MathUtils.degToRad(pShape.getRotation())
				);
				
				super.registerPhysicsConnector(pAttributes, pShape, body);
				
				super.mSVGDoc.addBody(pName, body);
			}else if(super.isHasSprite() || super.isDrawPrimitives()){
				//-- Velocitys to shape
				super.createPhysicHandler(pAttributes,pShape);
			}
		}
	}
	
	protected void createPath(final Attributes pAttributes){
		this.svgPath = new SVGPath(
			SAXUtils.getAttributeOrThrow(pAttributes, TAG_ATTRIBUTE_PATH),
			SAXUtils.getIntAttribute(pAttributes, TAG_ATTRIBUTE_CURVE_SEGMENTS, 4)
		);
	}
	
	@Override
	protected Shape createShape(final String pName, final Attributes pAttributes) {
		this.createPath(pAttributes);
		
		if(this.svgPath.isValid()){
			final String source = SAXUtils.getAttribute(pAttributes, TAG_ATTRIBUTE_SPRITESRC, "");
			Shape shape = null;
			if(source != "" ){
				//-- Sprite
				shape = super.createSprite(
					pName, 
					pAttributes, 
					source,
					this.svgPath.getAABB().getX(),
					this.svgPath.getAABB().getY(),
					this.svgPath.getAABB().getWidth(),
					this.svgPath.getAABB().getHeight(),
					this.svgPath.getAABB().getRotation(),
					this.svgPath.getAABB().getScaleX(),
					this.svgPath.getAABB().getScaleY()
				);
				super.setHasSprite(true);
			}else if(super.isHasPhysic() || super.isDrawPrimitives()){
				//-- Boundings
				shape = this.svgPath.getAABB();
				shape.setAlpha(0);
			}
			
			this.mTransformation.transformShape(shape);
			
			this.drawPrimitives(pName, pAttributes, shape);
			
			return shape;
		}
		return null;
	}
	
	protected void drawPrimitives(String pName, final Attributes pAttributes, final Shape pShape){
		if(super.isDrawPrimitives()){
			final SVGStyle style = new SVGStyle(pAttributes.getValue(TAG_ATTRIBUTE_STYLE));
			
			//-- fill test
			String colorstr = style.get(TAG_ATTRIBUTE_STYLE_FILLCOLOR); 
			if(!colorstr.equals("none") && this.svgPath.isClosed()){
				final float[] color = ParserUtil.getColor(colorstr);
				final List<Vector2> vecs = this.svgPath.getVerticesTriangleList();
				float[] triangle = new float[6];
				for(int i=0;i<vecs.size();i+=3){
					triangle[0] = vecs.get(i).x;
					triangle[1] = vecs.get(i).y;
					triangle[2] = vecs.get(i+1).x;
					triangle[3] = vecs.get(i+1).y;
					triangle[4] = vecs.get(i+2).x;
					triangle[5] = vecs.get(i+2).y;
					final TriangleShape tri = new TriangleShape(0, 0, triangle);
					tri.setColor(
						color[0], 
						color[1], 
						color[2], 
						style.getFloatValue(TAG_ATTRIBUTE_STYLE_FILLALPHA, 1)
					);
					pShape.attachChild(tri);
				}
			}
			
			colorstr = style.get(TAG_ATTRIBUTE_STYLE_LINECOLOR); 
			if(!colorstr.equals("none")){
				Render.lineRenderRel(
					this.svgPath.getVertices(), 
					pShape, 
					ParserUtil.getColor(colorstr), 
					style.getFloatValue(TAG_ATTRIBUTE_STYLE_LINEALPHA, 1), 
					style.getFloatValuePx(TAG_ATTRIBUTE_STYLE_LINEWIDTH, 1),
					this.svgPath.isClosed()
				);
			}
			
			//if(!super.isHasSprite()) super.mSVGDoc.addShape(pName, pShape);
		}
	}
}
